<template>
  <div>
    <Header></Header>
    <!-- 主容器 -->
    <div class="article-container">
      <!-- 左边文章 -->
      <div class="article-main-container">
        <!-- 文章主体 -->
        <Skeleton :loading="isLoadingSkeleton" :myType="'article'">
          <ArticleMain
            :articleInfo="articleInfo"
            :authorInfo="authorInfo"
          ></ArticleMain>
        </Skeleton>
      </div>
      <!-- 推荐文章 -->
      <div
        class="article-main-container recommend-container"
        v-show="!isLoadingSkeleton"
      >
        <div class="recommend-head"><span>相关推荐</span></div>
        <ArticleList
          :articlesList="recommendList"
          :myType="'article'"
        ></ArticleList>
        <div class="loading" v-show="isLoading">
          <i class="el-icon-loading"></i>
        </div>
      </div>
      <!-- 右侧信息 -->
      <ArticleAsideRight
        :authorInfo="authorInfo"
        :similarList="similarList"
        :navList="navList"
        :isLoadingSkeleton="isLoadingSkeleton"
        ref="article"
      ></ArticleAsideRight>
      <!-- 左侧点赞等列表 -->
      <ArticleAsideLeft :list="articleMeta"></ArticleAsideLeft>
    </div>
    <!-- 右下角 -->
    <SideBtn></SideBtn>
  </div>
</template>

<script>
import Header from '@/components/header/Header.vue'
import SideBtn from '@/components/sideButton/sidewButton.vue'
import Skeleton from '@/components/skeleton/Skeleton.vue'

import ArticleMain from './componets/ArticleMain.vue'
import ArticleList from '@/components/articlesList/ArticlesList.vue'
import ArticleAsideLeft from './componets/ArticleAsideLeft.vue'
import ArticleAsideRight from './componets/ArticleAsideRight.vue'

import mixin from '@/mixins/scroll'

import { mapMutations } from 'vuex'
import { marked } from 'marked'

// 本页面用到的接口
import {
  reqArticleDetail,
  reqArticleSimilar,
  reqArticleRecommend
} from '@/api/article'

export default {
  mixins: [mixin],
  data() {
    return {
      // 文章 id
      id: 0,
      // 推荐文章列表
      recommendList: [],
      // 相关文章列表
      similarList: [],
      // 文章内容
      articleInfo: {},
      // 作者信息
      authorInfo: {},
      // 是否加载骨架屏
      isLoadingSkeleton: true,
      // 推荐文章是否在加载
      isLoading: false,
      // 导航栏数据,
      navList: [],
      oldValue: 0
    }
  },
  created() {
    this.refersh()
  },
  methods: {
    ...mapMutations([
      'updateIsHideHead',
      'updateIsArriveBottom',
      'updateShouldFixed',
      'updateActived'
    ]),
    // 刷新页面数据
    refersh() {
      // 滚动条拉到顶部
      document.documentElement.scrollTop = 0
      // 从 url 获取到文章 ID
      this.id = this.$route.query.id
      // 重置 header 的状态
      this.updateIsHideHead(false)
      // 发起所有请求
      this.getInfo()
    },
    // 该页面中的所有请求
    async getInfo() {
      this.isLoadingSkeleton = true
      const { data: detail } = await reqArticleDetail(this.id)
      const { data: similar } = await reqArticleSimilar(this.id)
      const { data: recommend } = await reqArticleRecommend(this.id)

      this.articleInfo = detail.data.article_info
      this.authorInfo = detail.data.author_user_info
      // 转换 markdown 为 html 语言
      this.articleInfo.mark_content = marked(this.articleInfo.mark_content)
      this.similarList = similar.data
      this.isLoadingSkeleton = false
      this.recommendList = recommend.data
      // console.log(similar)
      // console.log(detail)
      // console.log(recommend)
    },
    // 连接新旧文章的数据
    async joinRecommendList() {
      // 防止多次请求
      if (this.isLoading) return
      this.isLoading = true
      const { data: recommend } = await reqArticleRecommend(this.id)
      this.recommendList = [...this.recommendList, ...recommend.data]
      this.isLoading = false
    },
    // 滚动事件
    scrolling() {
      // scrollTop是滚动条滚动时，距离顶部的距离
      let scrollTop = document.documentElement.scrollTop
      // windowHeight是可视区的高度
      let windowHeight = document.documentElement.clientHeight
      // scrollHeight是滚动条的总高度
      let scrollHeight = document.documentElement.scrollHeight
      // 滚动条滚动的距离
      let scrollStep = scrollTop - this.oldScrollTop

      // 文章目录顶部盒子的高度
      let heighet = this.$refs.article.$refs.headbox.clientHeight

      // 滚动目录的高度
      let dirScrollHeight =
        this.$refs.article.$refs.directoryScroll.clientHeight

      // 所有目录元素
      const dirItem = document.querySelectorAll('.directory-item')

      // 如果点击了回到顶部,重置目录的滚动条
      if (scrollTop === 0) {
        this.$refs.article.$refs.directoryScroll.scrollTop = 0
      }

      // 文章目录是否开启固定定位
      if (scrollTop > heighet) {
        this.updateShouldFixed(true)
      } else {
        this.updateShouldFixed(false)
      }

      // 更新——滚动前，滚动条距页面顶部的距离
      this.oldScrollTop = scrollTop

      // 头部区出现的条件
      if (scrollTop > 60 && scrollStep > 0) {
        this.updateIsHideHead(true)
      } else {
        this.updateIsHideHead(false)
      }

      // 回到顶部按钮出现的条件
      if (scrollTop > 900) {
        this.updateIsArriveBottom(true)
      } else {
        this.updateIsArriveBottom(false)
      }

      // 上拉触底加载的条件
      if (scrollHeight - scrollTop - windowHeight < 100) {
        this.joinRecommendList()
      }

      // 重上往下遍历文章标题，比较 '每一项到页面顶部的距离' 与 '页面顶部卷去的高度'
      for (let i = 0; i <= this.navList.length - 1; i++) {
        if (scrollTop <= this.navList[i].offsetTop + 60) {
          /**
           * this.updateActived(i)
           * 不能使用 vuex 来管理激活的 index 值
           * 因为不能在类名中使用计算属性
           * */
          this.$bus.$emit('actived', i)

          //当前激活元素相对于父元素顶部的距离
          let checkedOffsetTop = dirItem[i].offsetTop

          //差值
          let differ = i - this.oldValue
          console.log('目录differ', differ)

          if (differ === 0) {
            return
          }

          if (checkedOffsetTop > dirScrollHeight / 2) {
            // 目录滚动条滚动
            this.$refs.article.$refs.directoryScroll.scrollBy(0, 38 * differ)
            console.log('目录滚动条', checkedOffsetTop, dirScrollHeight / 2)
          }

          this.oldValue = i
          break
        }
      }
    },
    getAllTitle() {
      // 获取指定容器内的标题
      const markdown = document.querySelector('#markdown')
      const title = markdown.querySelectorAll('h1,h2,h3,h4')
      this.navList = Array.from(title)

      let arr = [1]
      for (let i = 0; i < this.navList.length - 1; i++) {
        // console.log(navList[i].localName.substr(-1))

        // 取标题等级
        const formar = this.navList[i].localName.substr(-1)
        const later = this.navList[i + 1].localName.substr(-1)
        // 是上一级的子级,取上一级 + 1
        if (formar < later) arr.push(arr[i] + 1)
        // 是上一级的父级,另起一行
        else if (formar > later) arr.push(1)
        // 与上一级同级,取上一级
        else if (formar === later) arr.push(arr[i])
      }
      console.log(arr)
      // 加上所有标题等级,目前我配置的是 '4级'
      this.navList.forEach((item, i) => {
        item.level = 'd' + arr[i]
      })
    }
  },
  computed: {
    // 过滤出需要的文章点赞等数据
    articleMeta() {
      const a = []
      a[0] = {
        count: this.articleInfo.digg_count,
        class: 'el-icon-thumb'
      }
      a[1] = {
        count: this.articleInfo.comment_count,
        class: 'el-icon-chat-line-round'
      }
      a[2] = {
        // 官网不显示
        // count: this.articleInfo.display_count,
        count: 0,
        class: 'el-icon-star-off'
      }
      a[3] = {
        count: this.articleInfo.display_count,
        class: 'el-icon-share'
      }
      return a
    }
  },
  watch: {
    /**  骨架屏关闭后,在下一次页面渲染中得到所有标题~ */
    isLoadingSkeleton: function () {
      console.log('监听骨架屏', this.isLoadingSkeleton)
      this.$nextTick(function () {
        this.getAllTitle()
      })
    }
  },
  components: {
    Header,
    ArticleAsideLeft,
    SideBtn,
    Skeleton,
    ArticleMain,
    ArticleList,
    ArticleAsideRight
  }
}
</script>

<style lang="less" scoped>
.article-container {
  position: relative;
  width: 100%;
  max-width: 1140px;
  margin: 6rem auto;

  .article-main-container {
    width: 820px;
    position: relative;
    background-color: var(--taojin-backgroung-color);
    margin-right: auto;
    padding-bottom: 1rem;
    border-radius: 2px;
  }

  .recommend-container {
    margin-top: 2rem;

    .recommend-head {
      padding: 0 20px;
      span {
        display: block;
        border-bottom: 1px solid #e4e6eb;
        font-size: 1.5rem;
        font-weight: 600;
        color: #252933;
        line-height: 30px;
        padding: 20px 0 16px;
      }
    }
  }
}

.loading {
  margin-top: 10px;
  text-align: center;
  padding-bottom: 1rem;
}
</style>
